// basic_utils.h

#ifndef DODO_BASIC_UTILS_H
#define DODO_BASIC_UTILS_H

#include <iostream>
#include <string>
#include <stdexcept>
#include <cstdlib>

#include <quigon/basic/constants.h>

namespace quigon
{

// Error reporting functor:
class Error_Report
{
public:
	Error_Report(
	        const std::string& prefix0 = "### QuiGon ###: error in function: ",
	        std::ostream& stream0 = std::cerr
	) : prefix(prefix0), stream(stream0) {}

	void operator()(const std::string& name, const std::string& message = "") const
	{
		using namespace std;
		stream << prefix << name;
		if (message.length() > 0)
			stream << " , with: " << message ;
		stream << endl;
	}
private:
	std::string prefix;
	std::ostream& stream;
};

// default error reporter.
const Error_Report func_err;

// convert environmental variables.
// return false only when invalid env var is met.
// return true when it's not env var or converting succeeds.
inline bool conv_env(std::string& raw_name)
{
	if (raw_name.length() == 0 || raw_name[0] != '$')
		return true;
	char *res = getenv(raw_name.substr(1).c_str());
	if (res == 0)
		return false;
	raw_name = res;
	return true;
}

// convert status num into a readable string.
std::string status_str(int status_num);

// print time
void print_time(std::ostream& stream = std::cout, const std::string& prefix = "# ");

void imbue(std::istream& stream, const std::string& format_str = "%Y-%m-%d %H:%M:%S");

void imbue(std::ostream& stream, const std::string& format_str = "%Y-%m-%d %H:%M:%S");

void imbue(std::iostream& stream, const std::string& format_str = "%Y-%m-%d %H:%M:%S");

}

#endif

